WebSocketServerHandler{ }
messageReceived{
  final Object msg=e.getMessage();
  if (msg instanceof HttpRequest) {
    handleHttpRequest(ctx,(HttpRequest)msg);
}
handleHttpRequest{
    sendHttpResponse(ctx,req,new DefaultHttpResponse(HTTP_1_1,FORBIDDEN));
  final WebSocketServerHandshakerFactory wsFactory=new WebSocketServerHandshakerFactory(this.getWebSocketLocation(req),null,false);
  this.handshaker=wsFactory.newHandshaker(req);
  if (this.handshaker == null) {
    wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel());
    this.handshaker.handshake(ctx.getChannel(),req);
}
handleWebSocketFrame{
  if (frame instanceof CloseWebSocketFrame) {
    this.handshaker.close(ctx.getChannel(),(CloseWebSocketFrame)frame);
    return;
    ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData()));
    return;
  if (!(frame instanceof TextWebSocketFrame)) {
  @SuppressWarnings("unchecked") final EJObject val=JSONDecoder.decode(((TextWebSocketFrame)frame).getText()).isObject();
  if (!activeChannels.containsKey(ctx.getChannel())) {
    final String commandType=val.get(MessageParts.CommandType.name()).isString().stringValue();
      final String sessionKey=val.get(MessageParts.ConnectionSessionKey.name()).isString().stringValue();
      if (sessionKey != null && (session=svc.getBus().getSessionBySessionId(sessionKey)) != null) {
        final LocalContext localContext=LocalContext.get(session);
        if (localContext.hasAttribute(SESSION_ATTR_WS_STATUS) && WEBSOCKET_ACTIVE.equals(localContext.getAttribute(String.class,SESSION_ATTR_WS_STATUS))) {
          activeChannels.put(ctx.getChannel(),session);
          svc.getBus().getQueueBySession(sessionKey).setDirectSocketChannel(new NettyQueueChannel(ctx.getChannel()));
          localContext.removeAttribute(MessageParts.WebSocketToken.name());
          localContext.removeAttribute(SESSION_ATTR_WS_STATUS);
          return;
        final EJString activationKey=val.get(MessageParts.WebSocketToken.name()).isString();
        if (activationKey == null || !WebSocketTokenManager.verifyOneTimeToken(session,activationKey.stringValue())) {
          final String reverseToken=WebSocketTokenManager.getNewOneTimeToken(session);
          localContext.setAttribute(MessageParts.WebSocketToken.name(),reverseToken);
          localContext.setAttribute(SESSION_ATTR_WS_STATUS,WEBSOCKET_AWAIT_ACTIVATION);
          sendMessage(ctx,getReverseChallenge(reverseToken));
          return;
      sendMessage(ctx,getFailedNegotiation("bad command"));
    session=activeChannels.get(ctx.getChannel());
    final Message msg=MessageFactory.createCommandMessage(session,((TextWebSocketFrame)frame).getText());
}
sendHttpResponse{
  if (res.getStatus().getCode() != 200) {
    res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(),CharsetUtil.UTF_8));
    setContentLength(res,res.getContent().readableBytes());
  final ChannelFuture f=ctx.getChannel().write(res);
  if (!isKeepAlive(req) || res.getStatus().getCode() != 200) {
    f.addListener(ChannelFutureListener.CLOSE);
}
exceptionCaught{
  e.getCause().printStackTrace();
  e.getChannel().close();
}
getWebSocketLocation{
  return "ws://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH;
}
sendMessage{
  ctx.getChannel().write(new TextWebSocketFrame(message));
}
getFailedNegotiation{
}
getSuccessfulNegotiation{
}
getReverseChallenge{
}
stop{
  for (  final Channel channel : activeChannels.keySet()) {
    channel.close();
}
getAttribute{
  return attributes.get(name);
}
getAttributeNames{
  return new Enumeration<String>(){
    private final Iterator<String> stringIterator=attributes.keySet().iterator();
      return stringIterator.hasNext();
      return stringIterator.next();
}
hasMoreElements{
  return stringIterator.hasNext();
}
nextElement{
  return stringIterator.next();
}
getCharacterEncoding{ }
setCharacterEncoding{ }
getContentLength{ }
getContentType{ }
getInputStream{ }
getParameter{
  final String[] parms=parameters.get(name);
  if (parms == null) {
    return parms[0];
}
getParameterNames{
  return new Enumeration<String>(){
    private final Iterator<String> stringIterator=parameters.keySet().iterator();
      return stringIterator.hasNext();
      return stringIterator.next();
}
hasMoreElements{
  return stringIterator.hasNext();
}
nextElement{
  return stringIterator.next();
}
getParameterValues{
  return parameters.get(name);
}
getParameterMap{ }
getProtocol{ }
getScheme{ }
getServerName{ }
getServerPort{ }
getReader{ }
getRemoteAddr{ }
getRemoteHost{ }
setAttribute{
  attributes.put(name,o);
}
removeAttribute{
  attributes.remove(name);
}
getLocale{ }
getLocales{ }
isSecure{ }
getRequestDispatcher{ }
getRealPath{ }
getRemotePort{ }
getLocalName{ }
getLocalAddr{ }
getLocalPort{ }
getServletContext{ }
startAsync{ }
startAsync{ }
isAsyncStarted{ }
isAsyncSupported{ }
getAsyncContext{ }
getDispatcherType{ }
getAuthType{ }
getCookies{
  return new Cookie[0];
}
getDateHeader{ }
getHeader{ }
getHeaders{ }
getHeaderNames{ }
getIntHeader{ }
getMethod{ }
getPathInfo{ }
getPathTranslated{ }
getContextPath{ }
getQueryString{ }
getRemoteUser{ }
isUserInRole{ }
getUserPrincipal{ }
getRequestedSessionId{ }
getRequestURI{ }
getRequestURL{ }
getServletPath{ }
getSession{ }
getSession{ }
isRequestedSessionIdValid{ }
isRequestedSessionIdFromCookie{ }
isRequestedSessionIdFromURL{ }
isRequestedSessionIdFromUrl{ }
authenticate{ }
login{ }
logout{ }
getParts{ }
getPart{ }
